package com.netty.go.handle;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.stereotype.Component;

@Component
public class NettyInitialHandle extends ChannelInitializer<NioSocketChannel> {
    @Override
    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
        // 数据分割符
        String delimiterStr = "##@##";
        ByteBuf delimiter = Unpooled.copiedBuffer(delimiterStr.getBytes());
        // 通过SocketChannel 去获取对应的管道pipeline
        ChannelPipeline pipeline  =  nioSocketChannel.pipeline();
        // TODO 通过管道，添加handler,HttpServerCodec 是netty自己提供的助手类
        // websocket基于http协议，所以需要http编解码器
        pipeline.addLast(new HttpServerCodec());
        //添加对于读写大数据流的支持
        pipeline.addLast(new ChunkedWriteHandler());
        // 对HttpMessage进行聚合，聚合成FullHttpRequest或FullHttpResponse
        // 几乎在Netty编程中，都会用到这个handle
        pipeline.addLast(new HttpObjectAggregator(1024*64));

        // ================= 上述是用于支持http协议的 ==============

        // 使用自定义处理拆包/沾包，并且每次查找的最大长度为1024字节
        pipeline.addLast(new DelimiterBasedFrameDecoder(1024, delimiter));

        // ================= 上述是用于自定义处理拆包/沾包，并且每次查找的最大长度为1024字节 ==============

        // 将上一步解码后的数据转码为Message实例
        pipeline.addLast(new MessageDecodeHandler());

        // ================= 上述是用于解码 ==============

        // 对发送客户端的数据进行编码，并添加数据分隔符
        pipeline.addLast(new MessageEncodeHandler(delimiterStr));

        // ================= 上述是用于编码 ==============

        // 自定义handler 对数据进行最终处理
        pipeline.addLast(new ChatHandler());
        // websocket 服务器处理的协议，用于给指定的客户端进行连接访问的路由地址
        // 比如处理一些握手动作(ping,pong)
        pipeline.addLast(new WebSocketServerProtocolHandler("/chat","WebSocket",true, 65536 * 10));
    }
}
